[% setvar title A Sandboxing mechanism for Perl 6 %]
<div id="archive-notice">
    <h3>This file is part of the Perl 6 Archive</h3>
    <p>To see what is currently happening visit <a href="http://www.perl6.org/">http://www.perl6.org/</a></p>
</div>
<div class='pod'>
<a name='TITLE'></a><h1>TITLE</h1>
<p>A Sandboxing mechanism for Perl 6</p>
<a name='VERSION'></a><h1>VERSION</h1>
<pre>  Maintainer: Matthew Byng-Maddick &lt;<a href='mailto:mbm@colondot.net'>mbm@colondot.net</a>&gt;
  Date: 30 Sep 2000
  Mailing List: <a href='mailto:perl6-internals@perl.org'>perl6-internals@perl.org</a>
  Number: 353
  Version: 1
  Status: Developing
  Co-Maintainer: Michael Schwern &lt;<a href='mailto:schwern@pobox.com'>schwern@pobox.com</a>&gt;</pre>
<a name='ABSTRACT'></a><h1>ABSTRACT</h1>
<p>The current Safe mechanism in Perl5 implements its tricks at opcode
level; this RFC proposes that some sandboxing features are needed by
the perl 6 runtime environment that stop untrusted code being allowed
to access/modify things it shouldn't. This comes from untrusted Perl
often being run as root with no good reason, and a need for root users
to maintain differing levels of trust with different modules.</p>
<p>This is not a replacement for <code>Safe</code>, merely a complement to it. There is
some overlap in between the two, but for the most part, <code>Safe</code> doesn't
give the granularity that is often needed. Some of this can only happen
at perl interpreter level.</p>
<a name='DESCRIPTION'></a><h1>DESCRIPTION</h1>
<p>This RFC attempts to deal with the practical problems of running untrusted
code within perl as a user with a high level of privilege. In it, a new
set of restrictions to certain interactions with the Operating System are
suggested, in several domains.</p>
<p>Various levels of protection are proposed.</p>
<a name='Filesystem Interaction'></a><h2>Filesystem Interaction</h2>
<p>This would restrict any filesystem calls. Possible trivial options are
off, tainted, on, although any combination of subdirectories could be
allowed, although <code>stat()</code> calls would be needed to check for the lack
of symlinks to something outside the tree in the path. Any restrictions
at all would taint the data read in.</p>
<p>In a subdirectory, one might want to allow read access, but not write
access. One might also want to specify that any writing is opened with
O_EXCL, in order that it behaves like a <code>set -C</code> in bash.</p>
<a name='INET Socket Interaction'></a><h2>INET Socket Interaction</h2>
<p>This would be similar to the filesystem, in that any kind of restriction
would cause the data to be tainted. The restriction could also be on what
ports the program is allowed to bind to (and which networks it will accept
connections from) , and what ports and networks it may open sockets to at
it's remote end.</p>
<a name='UNIX Domain Sockets'></a><h2>UNIX Domain Sockets</h2>
<p>These would be basically subject to the Filesystem constraints outlined
above, but with their own possible restrictions over and above.</p>
<a name='Memory and Resource Usage'></a><h2>Memory and Resource Usage</h2>
<p>Most of this can be done with something like <code>ulimit()</code> although it would
be good if Perl kept its own accounting of this, as it would enable Perl
to raise the exception, as opposed to the system just killing the process,
something which could be a problem on systems without this kind of
resource management.</p>
<a name='Allow exec() and eval() calls'></a><h2>Allow exec() and eval() calls</h2>
<p>Obviously these will be subject to the tainted data mechanism outlined
above, but you might want to restrict them altogether, in which case the
trapping at the language level is useful.</p>
<p>This RFC proposes that the standard tainting mechanism be used for the
handling of this data, but with similar exceptions being raised when, for
example, you try to read on a socket outside your allowed network range
(here read has been chosen because you may want to do your own processing
with the peer name).</p>
<p>In the case of an <code>eval STATEMENT</code> call (I'm not sure whether block ones
should count), the same sandboxing restrictions would apply.</p>
<a name='IMPLEMENTATION'></a><h1>IMPLEMENTATION</h1>
<p>A few issues are raised by this.</p>
<p>The security exceptions should be raised by <code>die()</code> in the normal way.</p>
<p>The simple off/on implementation can be made to be fast. A complex set of
rules will be slower, but this is considered an acceptable price to pay
for the security.</p>
<p>This <b>will</b> allow you to shoot yourself in the foot, and having thought
about it, I'm not sure there is much that you can do.</p>
<p>The sandbox should be locally scoped to its enclosing block (like the
behaviour of the current <code>local</code>), allowing it to become more restrictive
within the scope. A possibility is that within the same block (rather
than subblocks) the sandbox can become less restrictive, so you can close
down the box, <code>require</code> your untrusted code, and then open it a bit.</p>
<p>The one exception to this is that modules in perl's own lib directory
(tainting the <code>PERL6LIB</code> (?)  environment variable) might be allowed to
run with full privilege, as these have already been checked, and will
generally not be untrusted. This is a problem, as it is possible then to
implement a denial of resources attack, using the perl6 own modules. The
author will try and think of a way round this. :)</p>
<a name='Filesystem'></a><h2>Filesystem</h2>
<p>This is OK if it is just on/off, as all operations are then either
accepted or denied, and all filehandles could be tainted under the correct
circumstances. The allowed directories version of this will almost
certainly be more sophisticated, having to recurse through the path, and
either (i) following symlinks, (ii) ignoring them or (iii) throwing an
exception.</p>
<a name='Sockets'></a><h2>Sockets</h2>
<p>This is again similar. The on/off checks are way more trivial, although
port range checks are perhaps easier than the filesystem checking.</p>
<a name='Resource usage'></a><h2>Resource usage</h2>
<p>This could be implemented either entirely within Perl6, but this carries
all of the overheads of profiling code, or it could be implemented using
<code>ulimit()</code> on systems which have it, and catching the signal itself (I
haven't been able to find any references of what signal this is...)</p>
<a name='exec() type calls'></a><h2>exec() type calls</h2>
<p>This is just a case of on-off, although one could allow certain programs
to be run with this (much like sudo or similar), in the spirit of perl
flexibility.</p>
<a name='eval STATEMENT calls'></a><h2>eval STATEMENT calls</h2>
<p>These could be restricted altogether, but shoudl also be subject to the
same restrictions as their containing blocks. Thus a malicious program
shouldn't be able to do anything via an eval() that it couldn't already
do..</p>
<a name='Interface to the Language'></a><h2>Interface to the Language</h2>
<p>Interface to the language has been thought about, but the author does not
feel qualified to be authoritative on this point.</p>
<pre>   The syntax should be something like the current C&lt;use pragma&gt;
   directives, possibly something like:
      use sandbox 'fs' (. =&gt; ALLOW_SUBDIRS | ALLOW_READ |
          ALLOW_READ | ALLOW_CLOBBER);

   How this is actually implemented internally could be something like the
   $^H variable for C&lt;use strict&gt;, or it could be a perl builtin, although
   the complex data structures don't bode well for this.</pre>
<a name='REFERENCES'></a><h1>REFERENCES</h1>
<p>perldoc Safe</p>
<p>man ulimit</p>
</div>
